﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DateTimeSettingDescriptor.cs" company="Radical Research Ltd">
//   Copyright (c) Radical Research Ltd. The MIT License (MIT)
// </copyright>
// <summary>
//   
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace RadicalResearch.MiniState.Descriptors
{
    using System;

    /// <summary>Manages DateTime settings stored in a value collection.</summary>
    public class DateTimeSettingDescriptor : NumericSettingDescriptor
    {
        #region Constants and Fields

        /// <summary>
        ///   Epoch DateTime used for offset
        /// </summary>
        private DateTime epoch;

        #endregion

        #region Constructors and Destructors

        /// <summary>Initializes a new instance of the <see cref="DateTimeSettingDescriptor"/> class.</summary>
        /// <param name="valueKey">The value key.</param>
        /// <param name="isValidated">if set to <c>true</c> [is validated].</param>
        public DateTimeSettingDescriptor(string valueKey, bool isValidated)
            : this(valueKey, isValidated, 2000)
        {
        }

        /// <summary>Initializes a new instance of the <see cref="DateTimeSettingDescriptor"/> class.</summary>
        /// <param name="valueKey">The value key.</param>
        /// <param name="isValidated">if set to <c>true</c> [is validated].</param>
        /// <param name="epochYear">The epoch year.</param>
        public DateTimeSettingDescriptor(string valueKey, bool isValidated, int epochYear)
            : base(valueKey, isValidated, typeof(int))
        {
            this.epoch = new DateTime(epochYear, 1, 1, 0, 0, 0);
        }

        #endregion

        #region Public Methods

        /// <summary>Reads the value.</summary>
        /// <param name="values">The values.</param>
        /// <returns>value as an object</returns>
        public override object ReadValue(IValueCollection values)
        {
            int seconds = (int)base.ReadValue(values);
            return this.epoch.AddSeconds(seconds);
        }

        /// <summary>Writes the value.</summary>
        /// <param name="values">The values.</param>
        /// <param name="value">The value.</param>
        public override void WriteValue(IValueCollection values, object value)
        {
            if (this.epoch.CompareTo(value) > 0)
            {
                throw new ArgumentOutOfRangeException("value", "DateTime is before epoch");
            }

            DateTime dateTimeValue = (DateTime)value;
            TimeSpan ts = dateTimeValue - this.epoch;
            base.WriteValue(values, (int)ts.TotalSeconds);
        }

        #endregion
    }
}